/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package etherblocks.engine.states;

import com.jme3.app.Application;
import com.jme3.app.state.AppStateManager;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.collision.CollisionResults;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import etherblocks.game.World;
import com.cubes.BlockChunkControl;
import com.cubes.BlockChunkListener;
import com.cubes.BlockNavigator;
import com.cubes.BlockTerrainControl;
import com.cubes.Vector3Int;

/**
 *
 * @author Carl
 */
public class WorldAppState extends BaseAppState{

    public WorldAppState(World world){
        this.world = world;
    }
    private World world;
    private Node terrainNode;

    @Override
    public void initialize(AppStateManager stateManager, Application application){
        super.initialize(stateManager, application);
        BlockTerrainControl blockTerrain = world.getBlockTerrain();
        blockTerrain.addChunkListener(new BlockChunkListener(){

            @Override
            public void onSpatialUpdated(BlockChunkControl blockChunk){
                updateCollisionShape(blockChunk.getOptimizedGeometry_Opaque());
                updateCollisionShape(blockChunk.getOptimizedGeometry_Transparent());
            }
        });
        terrainNode = new Node();
        terrainNode.addControl(blockTerrain);
        terrainNode.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
        mainApplication.getRootNode().attachChild(terrainNode);
    }
    
    private void updateCollisionShape(Geometry chunkGeometry){
        RigidBodyControl rigidBodyControl = chunkGeometry.getControl(RigidBodyControl.class);
        if(chunkGeometry.getTriangleCount() > 0){
            if(rigidBodyControl != null){
                chunkGeometry.removeControl(rigidBodyControl);
                getAppState(BulletAppState.class).getPhysicsSpace().remove(rigidBodyControl);
            }
            rigidBodyControl = new RigidBodyControl(0);
            chunkGeometry.addControl(rigidBodyControl);
            getAppState(BulletAppState.class).getPhysicsSpace().add(rigidBodyControl);
        }
        else{
            if(rigidBodyControl != null){
                chunkGeometry.removeControl(rigidBodyControl);
            }
        }
    }
    
    public Vector3Int getCurrentPointedBlockLocation(boolean getNeighborLocation){
        CollisionResults results = mainApplication.getRayCastingResults(terrainNode);
        if(results.size() > 0){
            Vector3f collisionContactPoint = results.getClosestCollision().getContactPoint();
            return BlockNavigator.getPointedBlockLocation(world.getBlockTerrain(), collisionContactPoint, getNeighborLocation);
        }
        return null;
    }

    public World getWorld(){
        return world;
    }
}
